﻿using CleanArchitecture.Core.Interfaces;
using CleanArchitecture.Core.Interfaces.Cache;
using CleanArchitecture.Infrastructure.Entities;
using CleanArchitecture.Infrastructure.Entities.Business;
using CleanArchitecture.Infrastructure.Interfaces;
using CleanArchitecture.Infrastructure.Interfaces.Business;
using CleanArchitecture.Infrastructure.Interfaces.SystemLog;
using CleanArchitecture.Infrastructure.Models.Business.Columns;
using CleanArchitecture.Infrastructure.Models.Business.News;
using CleanArchitecture.Web.Factories;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;

namespace CleanArchitecture.Web.Controllers.Frontend.Article
{
    public class ArticleController : BaseFrontendController
    {
        #region Field
        private readonly ILocker _locker;
        private readonly IWebHelper _webHelper;
        private readonly IWorkContext _workContext;
        private readonly IColumnService _columnService;
        private readonly ISystemLogService _logService;
        private readonly IStaticCacheManager _cacheManager;
        private readonly ILanguageService _languageService;
        private readonly IActiveLogService _activelogService;
        private readonly IBusinessModelFactory _businessmodelFactory;
        private readonly string[] NoArticlePage = new string[]
        {//对于像联系我们等不需要对应文章的详情页，在此配置
         //* 注意： 
         //* 名称与 CleanArchitecture.Infrastructure.Models.Business.Columns.AvailableDetailLayout 
         //* 名称相同
            "ShowStrategeCooperation",
            "ShowContactus",
        };
        private readonly string ViewPagePath = "~/Views/Frontend/Article/{0}.cshtml";
        #endregion

        #region　Ctrl
        public ArticleController(
            ILocker locker,
            IWebHelper webHelper,
            IWorkContext workContext,
            IColumnService columnService,
            ISystemLogService logService,
            ILanguageService languageService,
            IStaticCacheManager cacheManager,
            IActiveLogService activelogService,
            IBusinessModelFactory businessmodelFact)
            : base(businessmodelFact)
        {
            _locker = locker;
            _webHelper = webHelper;
            _logService = logService;
            _workContext = workContext;
            _cacheManager = cacheManager;
            _columnService = columnService;
            _languageService = languageService;
            _activelogService = activelogService;
            _businessmodelFactory = businessmodelFact;
        }

        #endregion
        public IActionResult List(string columnhash, int page = 0)
        {
            //ensure it's invoked from our FrontPathRoute class
            if (HttpContext.Items["nowa.RedirectFromFrontPathRoute"] == null ||
                !Convert.ToBoolean(HttpContext.Items["nowa.RedirectFromFrontPathRoute"]))
            {
                return Redirect(Url.RouteUrl("Homepage"));
            }

            if (string.IsNullOrEmpty(columnhash))
                return Redirect(Url.RouteUrl("PageNotFound"));
            int columnId = columnhash.IdDecode(); //HashidsHelper.Decode(AuthenticationDefaultConfig.ItemIdHashSalt, columnhash);
            if (columnId == 0)
                return Redirect(Url.RouteUrl("PageNotFound"));
            IList<ColumnItemModel> allColumns = _columnService.GetColumnList();
            var column = allColumns.FirstOrDefault(c => c.Id == columnId);
            if (column == null/* || column.IsDisplay == EntityEnumConfig.YesorNo.No*/)
                return Redirect(Url.RouteUrl("PageNotFound"));
            //var currentCulture = CultureInfo.CurrentCulture;
            ViewBag.AllColumns = allColumns;
            ViewBag.CurrentColumn = column;
            GetRootColumn(column, allColumns);
            GetBreadColumns(column);
            //为了和Detail方法保持一致，在Layout中调用获取Title，传入值为null的NewsItemModel
            NewsItemModel newsItemModel = null;
            return View(string.Format(ViewPagePath, "List"), newsItemModel);
        }

        public IActionResult Detail(string columnhash, string itemhash = "")
        {
            //ensure it's invoked from our FrontPathRoute class
            //if (HttpContext.Items["nowa.RedirectFromFrontPathRoute"] == null ||
            //    !Convert.ToBoolean(HttpContext.Items["nowa.RedirectFromFrontPathRoute"]))
            //{
            //    return Redirect(Url.RouteUrl("Homepage"));
            //}

            if (string.IsNullOrEmpty(columnhash))
                return Redirect(Url.RouteUrl("PageNotFound"));
            int columnId = columnhash.IdDecode();//HashidsHelper.Decode(AuthenticationDefaultConfig.ItemIdHashSalt, columnhash);
            if (columnId == 0)
                return Redirect(Url.RouteUrl("PageNotFound"));
            IList<ColumnItemModel> allColumns = _columnService.GetColumnList();
            var column = allColumns.FirstOrDefault(c => c.Id == columnId);
            if (column == null || column.IsDisplay == EntityEnumConfig.YesorNo.No)
                return Redirect(Url.RouteUrl("PageNotFound"));

            NewsItemModel newsItemModel = null;
            //通过导航栏UrlRoute点击获取单页显示内容
            if (string.IsNullOrEmpty(itemhash))
            {
                //对于像联系我们等不需要对应文章的详情页，需要单独页面显示
                if (NoArticlePage.Length > 0 && NoArticlePage.Contains(column.LayoutDetailTemplate))
                {
                    ViewBag.AllColumns = allColumns;
                    ViewBag.CurrentColumn = column;
                    GetRootColumn(column, allColumns);
                    GetBreadColumns(column);
                    return View(string.Format(ViewPagePath, column.LayoutDetailTemplate));
                }
                newsItemModel = _businessmodelFactory.PrepareColumnNewsItemModelForFront(column.Id);
                var firstChild = allColumns.FirstOrDefault(ac => ac.ParentId == column.Id);
                if (/*column.ParentId == 0 &&*/ newsItemModel == null && firstChild != null)
                {//DavidLee 算法优化(递归)： 无论是几级分类导航
                 //如果分类导航没有对应页数据面，则展示其第一个子分类展示内容
                    return Redirect(firstChild.UrlRoute);
                }
                else if (newsItemModel == null && firstChild == null)
                    return Redirect(Url.RouteUrl("PageNotFound"));
                //else //newsItemModel != null
            }
            else
            {//通过页内文章链接点击显示具体文章/新闻
                int newsId = itemhash.IdDecode();
                newsItemModel = _businessmodelFactory.PrepareNewsItemModelForFront(newsId);
            }

            if (newsItemModel == null) return Redirect(Url.RouteUrl("PageNotFound"));
            else if (newsItemModel.WhoCanSee != EntityEnumConfig.WhoCanSee.EveryOne)
                return AccessDeniedView();

            //DavidLee 2020/07/08 增加对浏览文章/新闻的访问记录
            try
            {
                //get expiration time
                var expiration = TimeSpan.FromSeconds(120);
                string CacheKey = $"Visit_NewsItemId_{newsItemModel.Id.IdEncode()}";
                //execute task with lock
                bool isLogged = _locker.PerformActionWithLock(CacheKey, expiration, () =>
                {
                    var time = DateTime.UtcNow;
                    var logitem = new ActiveLog
                    {
                        ActiveName = ActiveLogName.VisitNewsPage,
                        EntityId = newsItemModel.Id,
                        EntityName = nameof(NewsItem),
                        CustomerId = 0,
                        Detail = "用户浏览新闻/文章",
                        IpAddress = _webHelper.GetCurrentIpAddress(),
                        CreatedOnTimeUtc = time,
                        Month = time.Month,
                        Year = time.Year
                    };
                    _activelogService.InsertLog(logitem);
                });
                if (isLogged)
                {
                    ViewBag.NewsVisitCount = _cacheManager.Get(CacheKey, () =>
                    {
                        var staticResult = _activelogService.StatisticsNewsCountsByNewsIds(new int[] { newsItemModel.Id });
                        if (staticResult != null)
                        {
                            if (staticResult.Count > 0)
                                return staticResult.First().VisitCount;
                        }
                        return 1;
                    }, expiration.Minutes);
                }
            }
            catch (Exception exc)
            {
                //log error
                _logService.Error($"记录用户浏览文章日志报错，文章Id：{itemhash}", exc);
            }

            ViewBag.AllColumns = allColumns;
            ViewBag.CurrentColumn = column;
            GetRootColumn(column, allColumns);
            GetBreadColumns(column);
            if (!column.LayoutDetailTemplate.Equals("DefaultSinglePage", StringComparison.CurrentCultureIgnoreCase))
                return View(string.Format(ViewPagePath, column.LayoutDetailTemplate), newsItemModel);

            return View(string.Format(ViewPagePath, "Detail"), newsItemModel);
        }

        /// <summary>
        /// 页面全文检索服务
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public IActionResult SearchEngine(string s, string lang = "zh")
        {
            IList<ColumnItemModel> allColumns = _columnService.GetColumnList();
            ViewBag.AllColumns = allColumns;
            ViewBag.CurrentColumn = null;
            ViewBag.SearchKeyword = s;
            var availableLangs = _languageService.GetLanguagesAll();
            var reqLang = availableLangs.FirstOrDefault(lan => lan.LanguageCode.Equals(lang, StringComparison.InvariantCultureIgnoreCase) && lan.IsActive == EntityEnumConfig.YesorNo.YES);
            _workContext.WorkingLanguage = reqLang == null ? availableLangs.First() : reqLang;
            return View(string.Format(ViewPagePath, "SearchEngine"));
        }
    }

}
